package com.sparrow.socket.tcp.session.manager;

import com.sparrow.common.schedule.queue.FixTimeDelayQueue;
import com.sparrow.socket.tcp.session.Session;
import com.sparrow.socket.tcp.session.listener.SessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 抽象的session管理器
 * @param <I>
 * @param <S>
 */
public abstract class AbstractSessionManager<I, S extends Session> {

    private static Logger logger = LoggerFactory.getLogger("session");

    protected ConcurrentHashMap<I, S> sessionMap = new ConcurrentHashMap<>();

    private List<SessionListener> listeners = new ArrayList<>();

    public void bind(S session, I identity) {
        session.setIdentity(identity);
        sessionMap.put(identity, session);
        this.listeners.forEach(l -> l.onSessionBind(session));
        logger.info("class:{} bind session {}, identity: {} channel {}", getClass().getSimpleName(), session.id(), identity, session.channelInfo());
    }

    public S getSession(I identity) {
        return sessionMap.get(identity);
    }

    public void close(S session) {
        if (session.getIdentity() == null) {
            return;
        }
        S removed = sessionMap.remove(session.getIdentity());
        if (removed != null) {
            this.listeners.forEach(l -> l.onSessionRemove(removed));
            logger.info("class:{} remove session {}, identity: {} channel {}", getClass().getSimpleName(), session.id(), session.getIdentity(), session.channelInfo());
        }
    }

    public Collection<S> getAllSession() {
        return new HashSet<>(sessionMap.values());
    }

    public void addListener(SessionListener listener) {
        this.listeners.add(listener);
    }

    public int size() {
        return sessionMap.size();
    }
}
